package com.ghy.seckill.controller;

import com.ghy.seckill.schedule.ScheduleTask;
import com.ghy.seckill.util.R;
import com.ghy.seckill.vo.RedisSkuVo;
import com.google.common.util.concurrent.RateLimiter;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.concurrent.TimeUnit;

@RestController
@Api(tags = "秒杀模块")
@CrossOrigin
public class SmsSeckillController {
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private ScheduleTask scheduleTask;

    private RateLimiter rateLimiter=RateLimiter.create(15);//放行请求数


    private final String upload_lock = "seckill:upload:lock";


    /**
     * 定时加载秒杀商品的定时任务 定时加载两天内需要进行的秒杀活动
     */
   //@Scheduled(fixedRate=1000) //    @Scheduled(cron = "0/5 * * * * ?")
    public void scheduledUpdate(){
        //分布式情况下，避免多台服务器同时去执行定时任务
        RLock lock = redissonClient.getLock(upload_lock);
        try {
            //加锁
            lock.lock(10, TimeUnit.SECONDS);
            scheduleTask.uploadSeckillProduct();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

    }
    @GetMapping("/getCurrentSeckillSkus")
    @ApiOperation("商品查询接口")
    public R getCurrentSeckillSkus(){
        List<RedisSkuVo> seckillSkus = scheduleTask.getCurrentSeckillSkus();
        return new R(200,"查询商品成功",seckillSkus);
    }

    /**
     * 使用令牌桶对秒杀接口做限流 设置一个等待时间如果在等待时间内没有获取到令牌则抛弃这个请求
     * @param promotionSessionId
     * @param killId
     * @param key
     * @param num
     * @return
     */
    @GetMapping("/seckill")
    @ApiOperation("秒杀接口")
    public R seckill(@ApiParam(value = "活动场次id", required = true) @RequestParam("promotionSessionId") String promotionSessionId,
                     @ApiParam(value = "商品id", required = true) @RequestParam("killId") String killId,
                     @ApiParam(value = "商品随机码 randomCode", required = true) @RequestParam("key") String key,
                     @ApiParam(value = "购买数量", required = true)@RequestParam("num") Integer num){
        boolean tryAcquire = rateLimiter.tryAcquire(2, TimeUnit.SECONDS);
        if (!tryAcquire){
            return new R(-100,"很遗憾，没抢到",null);
        }else {
            R seckill = scheduleTask.seckill(promotionSessionId, killId, key, num);
            return seckill;
        }

    }
}
